﻿using System;
using System.Collections.Generic;

namespace FDEE.Model
{
    /// <summary>
    /// PE大类墩柱
    /// </summary>
    internal abstract class CPEBase : ColumnBase
    {
        protected int Width, Length;
        protected double LenUpper; // 花瓶长度
        protected double LenLower;//下部加密长度
        protected RebarTendonDistribute MainLBarDistribute, AddLBarDistribute;// 顺桥向主筋A截面、加强筋配置规律
        protected RebarTendonDistribute MainWBarDistribute, AddWBarDistribute;// 横桥向主筋A截面、加强筋配置规律
        protected RebarTendonDistribute MainLBarDistributeB, AddLBarDistributeB;// 顺桥向主筋B截面、加强筋配置规律
        protected RebarTendonDistribute MainWBarDistributeB, AddWBarDistributeB;// 横桥向主筋B截面、加强筋配置规律
        protected RebarTendonDistribute MainLBarDistributeC, AddLBarDistributeC;// 顺桥向主筋C截面、加强筋配置规律
        protected RebarTendonDistribute MainWBarDistributeC, AddWBarDistributeC;// 横桥向主筋C截面、加强筋配置规律
        protected double wwSide, llSide,TopLength;
        protected double OuterRadius;
        protected double InnerRadius;
        protected double SideRadius;
/// <summary>
        /// (匝道)PE类墩柱基类
        /// </summary>
        /// <param name="typeName"></param>
        /// <param name="pierNumber"></param>
        /// <param name="st"></param>
        /// <param name="ww">截面横桥向宽度</param>
        /// <param name="ll">截面顺桥向长度</param>
        /// <param name="hh">墩净高</param>
        /// <param name="up">上部加密长度</param>
        /// <param name="low">下部加密长度</param>
        /// <param name="numRebarL">顺桥向外侧均布主筋个数</param>
        /// <param name="numRebarW">横桥向外侧均布主筋个数</param>
        /// <param name="mainDB">主筋直径</param>
        internal CPEBase(string typeName, string pierNumber, eColumnType ct, eSubType st,
            int ww, int ll, int hh, double up, double low, 
            double outerRadius,double innerRaius,double sideRadius,
            eDB mainDB,double wwS, double llS, double topL
            )
            : base(typeName, pierNumber, hh, ct,st, mainDB)
        {
            Width = ww;
            Length = ll;
            LenUpper = up;
            LenLower = low;
            wwSide = wwS;
            llSide = llS;
            TopLength = topL;
            OuterRadius = outerRadius;
            InnerRadius = innerRaius;
            SideRadius = sideRadius;
        }

        /// <summary>
        /// 根据圆上两点和圆半径 计算圆上任一点x值
        /// </summary>
        /// <param name="x1">圆上第一个点x值</param>
        /// <param name="y1">圆上第一个点x值</param>
        /// <param name="x2">圆上第二个点x值</param>
        /// <param name="y2">圆上第二个点x值</param>
        /// <param name="R">圆半径</param>
        /// <param name="y"></param>
        /// <param name="x"></param>
        public void CalArcCenter(double x1, double y1, double x2, double y2, double R, double y, ref double x,ref double CenterX, ref double CenterY)
        {
            //圆方程(x-CenterX)²+(y-CenterY)²=R²
            CenterX = 0;
            CenterY = 0;//圆心
            //根据数学公式计算
            List<string> CenterList = new List<string>();
            double c1 = (x2 * x2 - x1 * x1 + y2 * y2 - y1 * y1) / (2 * (x2 - x1));
            double c2 = (y2 - y1) / (x2 - x1);  //斜率
            double A = (c2 * c2 + 1);
            double B = (2 * x1 * c2 - 2 * c1 * c2 - 2 * y1);
            double C = x1 * x1 - 2 * x1 * c1 + c1 * c1 + y1 * y1 - R * R;
            //圆心(应该两个，根据具体情况定)
            CenterY = (-B - Math.Sqrt(B * B - 4 * A * C)) / (2 * A);
            CenterX = c1 - c2 * CenterY;

            CenterList.Add(Convert.ToString(CenterX));
            CenterList.Add(Convert.ToString(CenterY));
        
            //var v = Math.Sqrt(R * R - (y - CenterY) * (y - CenterY));
            //x值
            x = CenterX + Math.Sqrt(R * R - (y - CenterY) * (y - CenterY));
        }

        /// <summary>
        /// 根据长宽和长宽对应的变化值计算箍筋a,b,c三边的值
        /// </summary>
        /// <param name="W">宽</param>
        /// <param name="L">长</param>
        /// <param name="wwS">宽对应变化长度（宽两端varies）</param>
        /// <param name="llS">长对应变化长度（长两端varies）</param>
        /// <param name="a">六边形a长度</param>
        /// <param name="b">六边形b长度</param>
        /// <param name="c">六边形c长度</param>
        public void CalPara(double W, double L, double wwS, double llS, ref int a, ref int b, ref int c)
        {
            double ang = Math.Atan(llS / Math.Round(wwS, 2)); //A 参考角度
            if (llS == 0)
            {
                //最顶端矩形
                c = (int)(W - 2 * 50 - (int)MainRebarDB * 2);
                b = 0;
                a = (int)(L - 2 * 50 - (int)MainRebarDB * 2);
            }
            else
            {
                //根据三角函数计算三边的值
                double v2 = llS / Math.Sin(ang);

                var v0 = (50 - (50 / Math.Tan(ang)) * Math.Sin(ang)) / Math.Sin(ang);
                double A = W - wwS * 2 - ((50 - (50 / Math.Tan(ang)) * Math.Sin(ang)) / Math.Sin(ang)) * 2;

                ang = Math.Atan(wwS / Math.Round(llS, 2));  //C 参考角度
                var vv1 = (50 - (50 / Math.Tan(ang)) * Math.Sin(ang)) / Math.Sin(ang);
                double C = L - llS * 2 - ((50 - (50 / Math.Tan(ang)) * Math.Sin(ang)) / Math.Sin(ang)) * 2;

                double B = v2 - v0 - vv1;

                c = (int)GlobalFuncs.transmitNum(A);
                b = (int)GlobalFuncs.transmitNum(B);
                a = (int)GlobalFuncs.transmitNum(C);
            }

        }

        public override void SetConcreteVolume()
        {
            double A = Width * 0.001 * (Length * 0.001)- wwSide*0.001*llSide*0.001;
            double B= Width * 0.001 * (Length * 0.001);
            double C = Width * 0.001 * (TopLength*0.5 * 0.001);
            ConcreteVolumn =( A * (PierHeight- LenUpper )+C* LenUpper-(C-B) * LenUpper*0.5) * 0.001;
        }


        /// <summary>
        /// 计算净墩高范围内箍筋数量
        /// </summary>
        /// <param name="UpperSpace">上部间距，默认100mm</param>
        /// <param name="MidSpace">正常间距，默认300mm</param>
        /// <param name="LowerSpace">下部间距，默认100mm</param>
        /// <returns></returns>
        internal int GetStirrupNum(int UpperSpace = 100, int MidSpace = 300, int LowerSpace = 100)
        {
            double npts = 0;
            if ((PierHeight - LenLower - LenUpper) < 0)
            {
                npts = Math.Round((PierHeight - LenUpper) / LowerSpace, 0, MidpointRounding.AwayFromZero);
            }
            else
            {
                npts = Math.Round(LenLower / LowerSpace, 0, MidpointRounding.AwayFromZero) +
                    Math.Round((PierHeight - LenLower - LenUpper) / MidSpace, 0, MidpointRounding.AwayFromZero);
            }
                //+  Math.Round(LenUpper / UpperSpace, 0, MidpointRounding.AwayFromZero);
            return (int)npts+1;
        }
        //internal int GetStirrupNum(int UpperSpace = 100, int MidSpace = 300, int LowerSpace = 100)
        //{
        //    if ((PierHeight - LenLower - LenUpper) < 0)
        //    {
        //        throw new Exception("墩高配置错误");
        //    }
        //    double npts = Math.Round(LenLower / LowerSpace, 0, MidpointRounding.AwayFromZero) +
        //        Math.Round((PierHeight - LenLower - LenUpper) / MidSpace, 0, MidpointRounding.AwayFromZero);
        //    //+  Math.Round(LenUpper / UpperSpace, 0, MidpointRounding.AwayFromZero);
        //    return (int)npts + 1;
        //}
        /// <summary>
        /// 花瓶内轮廓曲线（R=4.5m）内距,输出单位m;
        /// </summary>
        /// <param name="h0">自下而上，单位m</param>
        /// <returns></returns>
        internal double GetXByH(double h0)
        {
            //-3448.6745069091517
            //    109.21392258179692
            //double x0 = -3.4486745;
            //double y0 = 0.1092139;
            double x0 = -3.4486745069091517;
            double y0 = 0.10921392258179692;
            double R = 4.5;
            double value = Math.Sqrt(R * R - Math.Pow((h0 - y0), 2.0));
            double dd = Math.Max(value + x0, -value + x0);
            return 0.5 * TopLength*1e-3 - dd ;
        }
        internal double GetXByH(double x0,double y0, double h0, double R = 4.5)
        {
            //-3448.6745069091517
            //    109.21392258179692
            //double x0 = -3.4486745;
            //double y0 = 0.1092139;
            //double x0 = -3.4486745069091517;
            //double y0 = 0.10921392258179692;
            //double R = 4.5;
            double value = Math.Sqrt(R * R - Math.Pow((h0 - y0), 2.0));
            double dd = Math.Max(value + x0, -value + x0);
            return 0.5 * TopLength * 1e-3 - dd;
        }
        /// <summary>
        /// 花瓶内轮廓曲线（R=4.0m）内距,输出单位m;
        /// </summary>
        /// <param name="h0">自下而上，单位m</param>
        /// <returns></returns>
        internal double GetX2ByH(double h0)
        {
            //-2698.8903501261793
            //    94.21235411409188

            //-2699.7064361830535
            //    48.460544320676689
            //double x0 = -2699.70643618 * 1e-3;
            //double y0 = 48.46054432 * 1e-3;
            double x0 = -2699.7064361830535 * 1e-3;
            double y0 = 48.460544320676689 * 1e-3;
            double R = 4.0;
            double value = Math.Sqrt(R*R - Math.Pow((h0 - y0), 2.0));
            double dd = Math.Max(value + x0, -value + x0);
            return 0.5 * TopLength * 1e-3 - dd;
        }
        internal double GetX2ByH(double x0,double y0,double h0, double R = 4.0)
        {
          
            //double x0 = -2699.7064361830535 * 1e-3;
            //double y0 = 48.460544320676689 * 1e-3;
            //double R = 4.0;
            double value = Math.Sqrt(R * R - Math.Pow((h0 - y0), 2.0));
            double dd = Math.Max(value + x0, -value + x0);
            return 0.5 * TopLength * 1e-3 - dd;
        }
        /// <summary>
        /// 花瓶顺桥向内轮廓内距
        /// </summary>
        /// <param name="h0"></param>
        /// <returns></returns>
        internal double GetSideXByH(double h0)
        {
            double x0 = -19774.99822016 * 1e-3;
            double y0 = 8.43763349 * 1e-3;
            double R = 20.0;
            double value = Math.Sqrt(R * R - Math.Pow((h0 - y0), 2.0));
            double dd = Math.Max(value + x0, -value + x0);
            return 0.5 * Length * 1e-3 - dd;
        }
        internal double GetSideXByH(double x0, double y0,double h0, double R = 20.0)
        {
            //double x0 = -19774.99822016 * 1e-3;
            //double y0 = 8.43763349 * 1e-3;
            //double R = 20.0;
            double value = Math.Sqrt(R * R - Math.Pow((h0 - y0), 2.0));
            double dd = Math.Max(value + x0, -value + x0);
            return 0.5 * Length * 1e-3 - dd;
        }

    }





}
